package garin.parse.io;

import static java.lang.Character.toLowerCase;
import garin.parse.Token;

import java.io.IOException;

public abstract class AbstractSource implements Source {
	private SetValueObserver setValueObserver = new SetValueObserver() {
		public void onSetValue(final Token token) {
		}
	};
	
	/**
	 * @param match
	 * @return true if char is a match
	 */
	public final boolean is(final char match) {
		return is(match, true);
	}
	
	public boolean is(final char c, final boolean cs) {
		final char ch = ch();
		return cs ? c == ch : toLowerCase(ch) == toLowerCase(c);
	}
	
	public final boolean is(final String match) throws IOException {
		return is(match, true);
	}
	
	/**
	 * @param match
	 *            test
	 * @return true if match
	 * @throws IOException
	 */
	public final boolean is(final String match, final boolean cs)
			throws IOException {
		final long last = at();
		final int len = match.length();
		int p = -1;
		while (++p < len && is(match.charAt(p), cs))
			go();
		go(last);
		return p == match.length();
	}
	
	public final boolean isWhitespace() {
		return Character.isWhitespace(ch());
	}
	
	public void onSetValue(final Token token) {
	}
	
	public void read(Token token) throws Exception {
		while (token.go())
			token = token.on();
		token = token.on();
	}
	
	public SetValueObserver setValueObserver() {
		return setValueObserver;
	}
	
	public void setValueObserver(final SetValueObserver o) {
		setValueObserver = o;
	}
}
